package com.ljwy.gun;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.ljwy.gun.adapter.EpcAdapter;
import com.ljwy.gun.bean.DaKaInfo;
import com.ljwy.gun.okgoHelper.HttpRequestHelper;
import com.ljwy.gun.okgoHelper.JsonCallback;
import com.ljwy.gun.utils.ToastUtils;
import com.ljwy.gun.utils.cache.ACacheHelper;
import com.lzy.okgo.model.Response;
import com.rscja.deviceapi.entity.UHFTAGInfo;
import com.rscja.deviceapi.interfaces.ConnectionStatus;
import com.rscja.deviceapi.interfaces.ConnectionStatusCallback;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static com.ljwy.gun.utils.Constant.BT_NAME;
import static com.ljwy.gun.utils.Constant.GET_EPC;
import static com.ljwy.gun.utils.Constant.IP;

public class MainActivity extends BaseActivity  {

    @BindView(R.id.address_tv)
    TextView addressTv;
    @BindView(R.id.stats_tv)
    TextView statsTv;
    @BindView(R.id.lv)
    ListView lv;
    @BindView(R.id.power_tv)
    TextView powerTv;
    @BindView(R.id.cp_tv)
    TextView cpTv;
    @BindView(R.id.stop_btn)
    Button stopBtn;
    private BTStatus btStatus = new BTStatus();
    private long firstTime;
    final int FLAG_START = 0;//开始
    final int FLAG_STOP = 1;//停止
    final int FLAG_UPDATE_TIME = 2; // 更新时间
    final int FLAG_UHFINFO_LIST = 5;
    final int FLAG_SUCCESS = 10;//成功
    final int FLAG_FAIL = 11;//失败
    private HashMap<String, String> tagMap = new HashMap<>();
    private List<String> tempDatas = new ArrayList<>();
    private SimpleAdapter adapter;
    public static final String TAG_DATA = "tagData";
    public static final String TAG_EPC = "tagEpc";
    public static final String TAG_TID = "tagTid";
    public static final String TAG_LEN = "tagLen";
    public static final String TAG_COUNT = "tagCount";
    public static final String TAG_RSSI = "tagRssi";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        String address = ACacheHelper.getInstance().getString(BT_NAME, "");
        if (TextUtils.isEmpty(address)) {
            ToastUtils.showShort("蓝牙地址为空");
            finish();
        }
        connect(address);
    }

    private void connect(String deviceAddress) {
        if (uhf.getConnectStatus() == ConnectionStatus.CONNECTING) {
            ToastUtils.showShort("连接中...");
        } else {
            uhf.connect(deviceAddress, btStatus);
        }
    }


    @OnClick(R.id.stop_btn)
    public void onViewClicked() {
        if (isLoopFlag) {
            stopInventory();
        } else {
            startThread();
        }
    }

    class BTStatus implements ConnectionStatusCallback<Object> {
        @Override
        public void getStatus(final ConnectionStatus connectionStatus, final Object device1) {
            runOnUiThread(new Runnable() {
                public void run() {
                    BluetoothDevice device = (BluetoothDevice) device1;
                    if (device == null) {
                        statsTv.setText("蓝牙地址错误");
                        statsTv.setTextColor(Color.RED);
                    } else {
                        if (connectionStatus == ConnectionStatus.CONNECTED) {
                            addressTv.setText(String.format("当前连接地址:%s", device.getAddress()));
                            statsTv.setText(String.format("连接状态:%s", "已连接"));
                            statsTv.setTextColor(Color.GREEN);
                            ToastUtils.showShort("连接成功");
                            cpTv.setText("当前CP点:" + ACacheHelper.getInstance().getString("CPNAME", "未知"));
                            runOnUiThread(() -> {
                                try {
                                    Thread.sleep(2000);
                                    ToastUtils.showShort(uhf.setFrequencyMode(0x08) ? "美国标准" : "设置失败");
                                    ToastUtils.showLong(uhf.setPower(30) ? "输出功率成功" : "输出功率失败");
                                    Log.e("TAG", uhf.getFrequencyMode() + "===" + uhf.getPower());
                                    keyDown();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            });

                            new PowerTimer(TOTAL, MER).start();
                        } else if (connectionStatus == ConnectionStatus.DISCONNECTED) {
                            isLoopFlag = false;
                            addressTv.setText(String.format("当前连接地址:%s", TextUtils.isEmpty(device.getAddress()) ? "地址不对" : device.getAddress()));
                            statsTv.setText(String.format("连接状态:%s", "已断开或拒绝"));
                            statsTv.setTextColor(Color.RED);
                            ToastUtils.showShort("连接失败");
                        } else if (connectionStatus == ConnectionStatus.CONNECTING) {
                            addressTv.setText("连接中...");
                            statsTv.setText("连接中...");
                        }
                    }
                }
            });
        }
    }

    private void keyDown() {
        uhf.setKeyEventCallback(keycode -> {
            if (uhf.getConnectStatus() == ConnectionStatus.CONNECTED) {
                if (isLoopFlag) {
                    stopInventory();
                    stopBtn.setText("开始接收");
                    isLoopFlag = false;
                } else {
                    startThread();
                    stopBtn.setText("停止接收");
                    isLoopFlag = true;
                }
            }
        });
    }

    boolean isLoopFlag = false;
    boolean isRuning = false;

    public void startThread() {
        if (isRuning) {
            return;
        }
        isRuning = true;
        new TagThread().start();
    }


    class TagThread extends Thread {

        public void run() {
            Message msg = handler.obtainMessage(FLAG_START);
            if (uhf.startInventoryTag()) {
                isLoopFlag = true;
                long mStrTime = System.currentTimeMillis();
                msg.arg1 = FLAG_SUCCESS;
            } else {
                msg.arg1 = FLAG_FAIL;
            }
            handler.sendMessage(msg);
            isRuning = false;//执行完成设置成false
            long startTime = System.currentTimeMillis();
            while (isLoopFlag) {
                List<UHFTAGInfo> list = getUHFInfo();
                if (list == null || list.size() == 0) {
                    SystemClock.sleep(1);
                } else {
                    // Utils.playSound(1);
                    handler.sendMessage(handler.obtainMessage(FLAG_UHFINFO_LIST, list));
                }
                if (System.currentTimeMillis() - startTime > 100) {
                    startTime = System.currentTimeMillis();
                    handler.sendEmptyMessage(FLAG_UPDATE_TIME);
                }

            }
            stopInventory();
        }
    }

    /**
     * 停止识别
     */
    private void stopInventory() {
        isLoopFlag = false;
        // cancelInventoryTask();
        boolean result = uhf.stopInventory();
        ConnectionStatus connectionStatus = uhf.getConnectStatus();
        Message msg = handler.obtainMessage(FLAG_STOP);
        if (result || connectionStatus == ConnectionStatus.DISCONNECTED) {
            msg.arg1 = FLAG_SUCCESS;
        } else {
            msg.arg1 = FLAG_FAIL;
        }
        if (connectionStatus == ConnectionStatus.CONNECTED) {
            //在连接的情况下，结束之后继续接收未接收完的数据
            //getUHFInfoEx();
        }
        handler.sendMessage(msg);
    }


    private synchronized List<UHFTAGInfo> getUHFInfo() {
        return uhf.readTagFromBufferList_EpcTidUser();
    }

    private static ConcurrentHashMap<String, String> hashMapHttps = new ConcurrentHashMap<>();
    private static final String ERRORINFO = "ERRORINFO";
    private String time = getCurrentDate();
    HashMap<String, String> hashMap = new HashMap<>();
    private List<UHFTAGInfo> mData = new ArrayList<>();
    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        private EpcAdapter adapter;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case FLAG_STOP:
                    if (msg.arg1 == FLAG_SUCCESS) {
                        //停止成功
                    } else {
                        //停止失败
                        //   Utils.playSound(2);
                        //Toast.makeText(mContext, R.string.uhf_msg_inventory_stop_fail, Toast.LENGTH_SHORT).show();
                    }
                    break;
                case FLAG_UHFINFO_LIST:
                    List<UHFTAGInfo> list = (List<UHFTAGInfo>) msg.obj;
                    addEPCToList(list, true);
                    break;
                case FLAG_START:
                    if (msg.arg1 == FLAG_SUCCESS) {
                        //开始读取标签成功
                    } else {
                        //开始读取标签失败
                        //  Utils.playSound(2);
                    }
                    break;
                case FLAG_UPDATE_TIME:
                    break;
            }
        }
    };

    public String getCurrentDate() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(calendar.getTime());
        return date;
    }

    private static int TOTAL = 24 * 60 * 60 * 1000;
    private static int MER = 30 * 1000;

    class PowerTimer extends CountDownTimer {

        public PowerTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            if (uhf != null) {
                powerTv.setText("电量:" + uhf.getPower() + "%");
            }
            if (isLoopFlag) {
                List<DaKaInfo.DataBean> list = ACacheHelper.getInstance().get().getAsObject(ERRORINFO);
                if (list != null && list.size() > 0) {
                    for (int i = 0; i < list.size(); i++) {
                        String epc = list.get(i).getUid();
                        hashMap.clear();
                        hashMap.put("time", list.get(i).getWhen());
                        hashMap.put("terminal_no", epc);
                        hashMap.put("cp_no", ACacheHelper.getInstance().getString("CPID", ""));
                        HttpRequestHelper.getRequest(mContext, IP + GET_EPC, hashMap, false, new JsonCallback<String>() {
                            @Override
                            public void onSuccess(Response<String> response) {
                                Log.e("TAG", response.body());
                            }

                            @Override
                            public void onError(Response<String> response) {
                                super.onError(response);
                                DaKaInfo.DataBean info = new DaKaInfo.DataBean(time, epc);
                                ACacheHelper.getInstance().get().put(ERRORINFO, info);
                            }
                        });
                    }
                }
            }
        }

        @Override
        public void onFinish() {

        }
    }

    @Override
    public void onBackPressed() {
        long secondTime = System.currentTimeMillis();
        if (secondTime - firstTime > 2000) {
            ToastUtils.showShort("再按一次退出程序");
            firstTime = secondTime;
        } else {
            finish();
        }
    }

    private StringBuilder stringBuilder = new StringBuilder();
    private ArrayList<HashMap<String, String>> tagList = new ArrayList<>();

    private void addEPCToList(List<UHFTAGInfo> list, boolean isRepeat) {
        for (int k = 0; k < list.size(); k++) {
            UHFTAGInfo uhftagInfo = list.get(k);
            if (!TextUtils.isEmpty(uhftagInfo.getEPC())) {

                int index = checkIsExist(uhftagInfo.getEPC());

                stringBuilder.setLength(0);
                stringBuilder.append("EPC:");
                stringBuilder.append(uhftagInfo.getEPC());
                if (!TextUtils.isEmpty(uhftagInfo.getTid())) {
                    stringBuilder.append("\r\nTID:");
                    stringBuilder.append(uhftagInfo.getTid());
                }
                if (!TextUtils.isEmpty(uhftagInfo.getUser())) {
                    stringBuilder.append("\r\nUSER:");
                    stringBuilder.append(uhftagInfo.getUser());
                }

                tagMap.put(MainActivity.TAG_EPC, uhftagInfo.getEPC());
                tagMap.put(MainActivity.TAG_DATA, stringBuilder.toString());
                tagMap.put(MainActivity.TAG_COUNT, String.valueOf(1));
                tagMap.put(MainActivity.TAG_RSSI, uhftagInfo.getRssi());
                if (index == -1) {
                    tagList.add(tagMap);
                    tempDatas.add(uhftagInfo.getEPC());

                } else if (isRepeat) {
                }
            }
        }
        if (tagList != null && tagList.size() > 0) {
            if (adapter == null) {
                adapter = new SimpleAdapter(mContext, tagList, R.layout.listtag_items,
                        new String[]{MainActivity.TAG_DATA, MainActivity.TAG_LEN, MainActivity.TAG_COUNT, MainActivity.TAG_RSSI},
                        new int[]{R.id.TvTagUii, R.id.TvTagLen, R.id.TvTagCount,
                                R.id.TvTagRssi});
                lv.setAdapter(adapter);
            } else {
                adapter.notifyDataSetChanged();
            }
//            for (int i = 0; i < tagList.size(); i++) {
//                String epc = list.get(i).getEPC();
//                hashMap.clear();
//                hashMap.put("time", time);
//                hashMap.put("terminal_no", epc);
//                hashMap.put("cp_no", ACacheHelper.getInstance().getString("CPID", ""));
//                HttpRequestHelper.getRequest(mContext, IP + GET_EPC, hashMap, false, new JsonCallback<String>() {
//                    @Override
//                    public void onSuccess(Response<String> response) {
//                        DaKaErrorInfo errorInfo = GsonConvert.fromJson(response.body(), DaKaErrorInfo.class);
//                        if (errorInfo.getMsg().getCode() == 51110) {
//                            ToastUtils.showShort(errorInfo.getMsg().getInfo());
//                        }
//                    }
//
//                    @Override
//                    public void onError(Response<String> response) {
//                        super.onError(response);
//                        DaKaInfo.DataBean info = new DaKaInfo.DataBean(time, epc);
//                        ACacheHelper.getInstance().get().put(ERRORINFO, info);
//                    }
//                });
//            }
        }
    }

    /**
     * 判断EPC是否在列表中
     *
     * @param epc 索引
     * @return
     */
    public int checkIsExist(String epc) {
        if (TextUtils.isEmpty(epc)) {
            return -1;
        }
        return binarySearch(tempDatas, epc);
    }

    /**
     * 二分查找，找到该值在数组中的下标，否则为-1
     */
    static int binarySearch(List<String> array, String src) {
        int left = 0;
        int right = array.size() - 1;
        // 这里必须是 <=
        while (left <= right) {
            if (compareString(array.get(left), src)) {
                return left;
            } else if (left != right) {
                if (compareString(array.get(right), src))
                    return right;
            }
            left++;
            right--;
        }
        return -1;
    }

    static boolean compareString(String str1, String str2) {
        if (str1.length() != str2.length()) {
            return false;
        } else if (str1.hashCode() != str2.hashCode()) {
            return false;
        } else {
            char[] value1 = str1.toCharArray();
            char[] value2 = str2.toCharArray();
            int size = value1.length;
            for (int k = 0; k < size; k++) {
                if (value1[k] != value2[k]) {
                    return false;
                }
            }
            return true;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        uhf.free();
        ToastUtils.showShort("蓝牙已断开");
    }
}
